#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <net/if.h>
#include <unistd.h>

// 打印MAC地址
void print_mac(const unsigned char *mac) {
    printf("%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

int main() {
    int fd;
    struct ifreq ifr;
    struct sockaddr_in sin;
    char buffer[ETH_FRAME_LEN];
    struct ethhdr *eth;
    int frame_length;
    // 用于统计帧数和每种类型帧的数量
    int total_frames = 0;
    int ip_frames = 0;
    int arp_frames = 0;
    int rarp_frames = 0;

    // 创建原始套接字
    if ((fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
        perror("socket");
        exit(1);
    }

    // 设置网卡为混杂模式
    strcpy(ifr.ifr_name, "ens33");
    if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
        perror("SIOCGIFFLAGS");
        close(fd);
        exit(1);
    }
    ifr.ifr_flags |= IFF_PROMISC;
    if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
        perror("SIOCSIFFLAGS");
        close(fd);
        exit(1);
    }

    // 开始捕获并分析数据帧
    while (1) {
        // 从套接字读取数据帧
        frame_length = read(fd, buffer, sizeof(buffer));
        if (frame_length < 0) {
            perror("read");
            continue;
        }

        eth = (struct ethhdr *)buffer;
        total_frames++;

        printf("Frame length: %d\n", frame_length);
        printf("Destination MAC: ");
        print_mac(eth->h_dest);
        printf("\n");
        printf("Source MAC: ");
        print_mac(eth->h_source);
        printf("\n");
        printf("Protocol: 0x%04x\n", ntohs(eth->h_proto));

        // 统计不同类型数据帧的数量
        switch (ntohs(eth->h_proto)) {
            case ETH_P_IP:
                ip_frames++;
                break;
            case ETH_P_ARP:
                arp_frames++;
                break;
            case ETH_P_RARP:
                rarp_frames++;
                break;
            default:
                break;
        }
        
        printf("------------------------\n");
        // 打印统计信息
        printf("\nTotal Frames Captured: %d\n", total_frames);
        printf("IP Frames: %d (%.2f%%)\n", ip_frames, (float)ip_frames / total_frames * 100);
        printf("ARP Frames: %d (%.2f%%)\n", arp_frames, (float)arp_frames / total_frames * 100);
        printf("RARP Frames: %d (%.2f%%)\n", rarp_frames, (float)rarp_frames / total_frames * 100);
        printf("------------------------\n");
    }

    // 关闭套接字，这里正常情况下不会执行到，因为是死循环
    close(fd);

    return 0;
}